package com.tnsw.noxnox.settopbox;

import java.net.Socket;
import java.util.ArrayList;

import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.apache.http.conn.params.ConnManagerParamBean;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.DefaultHttpRequestFactory;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.impl.io.HttpRequestParser;
import org.apache.http.impl.io.SocketInputBuffer;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;

import android.content.Context;
import android.util.Log;

import com.tnsw.coreutils.AsyncManager;

public abstract class STBHttpBuilderBase extends Thread {
	
	private String tag = "STBHttpBuilderBase";
	protected AsyncManager asyncManager;
	protected Context context;
	protected DefaultHttpServerConnection serverConnection;
	protected Socket socket;

	public STBHttpBuilderBase(Context context, Socket socket) {
		this.context = context;
		this.socket = socket;
		this.asyncManager = AsyncManager.getInstance();
		
		this.serverConnection = new DefaultHttpServerConnection();
	}
	
	public void startThread() {
		super.start();
	}
	
	public static String createHttpResponse(String version, String statusCode, String statusText, ArrayList<Header> headers) {
		StringBuffer sb = new StringBuffer();
		
		sb.append("HTTP/" + version + " " + statusCode + " " + statusText + "\r\n");
		if (headers != null) {
			for (Header h : headers) {
				sb.append(h.getName() + ": " + h.getValue());
				sb.append("\r\n");
			}
		}
		
		sb.append("\r\n");
		
		return(sb.toString());
	}
	
	protected void onException(Socket socket, HttpRequest httpRequest, Exception e) {
		
	}
	
	protected abstract void process(Context context, HttpRequest request, Socket socket, DefaultHttpServerConnection serverConnection);
	
	@Override
	public void run() {
		super.run();
		
		HttpRequest request = null;
		
		try {
			this.serverConnection.bind(this.socket, new BasicHttpParams());
			
			BasicHttpParams httpParams = new BasicHttpParams();
			
			int maxConn = ConnManagerParams.getMaxTotalConnections(httpParams);
			this.asyncManager.appendNetworkLog("maxConn=" + maxConn);
			SocketInputBuffer inBuffer = new SocketInputBuffer(this.socket, HttpConnectionParams.getSocketBufferSize(httpParams), httpParams);
			HttpRequestParser reqParser = new HttpRequestParser(inBuffer, null, new DefaultHttpRequestFactory(), httpParams);
			request = (HttpRequest) reqParser.parse();
			
			this.process(this.context, request, this.socket, this.serverConnection);
			
			//if (this.socket.isClosed() == false) {
				this.socket.close();
				Log.d(tag, "Socket is closed");
				
			//}
			
			
		} catch (Exception e) {
			Log.e(tag, "run() - " + e.toString(), e);
			this.onException(this.socket, request, e);
		}
	}
	
	
}
